﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>继承</title>
    
    <script type="text/javascript">
        function Parent(name) {
            this.Username = name;
            this.PrintName = function () {
                alert(this.Username);
            }
        }

        // 继承：第一种方式：对象冒充式
        function Child(name, password) {
            this.Method = Parent;
            // 用this.Method的方式调用Parent函数，将Child的this传递给Parent，
            // 所以Child也会拥有Parent的属性。
            // 注：这里若直接写成Parent(name)，则其方法中的属性不会赋给子类。
            this.Method(name)
            delete this.Method;

            this.Password = password;
            this.PrintPassword = function () {
                alert(this.Password);
            }
        }

//        var parent = new Parent("parent");
//        parent.PrintName();

//        var child = new Child("child", "password1");
//        child.PrintName();
//        child.PrintPassword();

//        // 不用new调用时，Parent当方法用。这时的this是当前对象window的属性。
//        Parent("zhangsan");
//        alert(Username);
//        alert(window.Username);



        // 继承：第二种方法：call方法
        function Child2(name, password) {
            // JS中的函数都具有call方法，
            // 其中第一个参数将值赋给函数中的this，第二个参数开始逐一赋给函数的参数。
            Parent.call(this, name);

            this.Password = password;
            this.PrintPassword = function () {
                alert(this.Password);
            }
        }
//        var child2 = new Child2("zhangsan", "password2");
//        child2.PrintName();
//        child2.PrintPassword();

        // 第三种继承方式：Apply方法方式
        function Child3(name, password) {
            // JS中的函数都具有apply方法，
            // 其中第一个参数将值赋给函数中的this，第二个参数为该函数的参数组成的数组。
            Parent.apply(this, new Array(name));

            this.Password = password;
            this.PrintPassword = function () {
                alert(this.Password);
            }
        }
//        var child3 = new Child2("zhangsan", "password3");
//        child3.PrintName();
//        child3.PrintPassword();

        // 第四种继承方式：原型链模式
        // 与原型方式定义对象一样，该模式的缺点是构造函数不能传参。
        function Person() { }
        Person.prototype.Name = "aa";
        Person.prototype.PrintName = function () {
            alert(this.Name);
        }

        function Man() { }
        Man.prototype = new Person();
        Man.prototype.Password = "11";
        Man.prototype.PrintPassword = function () {
            alert(this.Password);
        }

//        var man = new Man();
//        man.Name = "zhangsan";
//        man.Password = "password4";
//        man.PrintName();
//        man.PrintPassword();

        // 第五种继承方式：混合模式
        function Parent2(name) {
            this.Name = name;
        }
        Parent2.prototype.PrintName = function () {
            alert(this.Name);
        }

        function Child5(name, password) {
            Parent2.call(this, name);
            this.Password = password;
        }
        Child5.prototype = new Parent2();
        Child5.prototype.PrintPassword = function () {
            alert(this.Password);
        }
        var child5 = new Child5("zhangsan", "password5");
        child5.PrintName();
        child5.PrintPassword();
    </script>
</head>
<body>

</body>
</html>
